package com.yudean.esb.service.impl.erp;

import com.yudean.esb.dao.mds.MdsERPFinIndexDao;
import com.yudean.esb.domain.mds.MdsERPFinIndex;
import com.yudean.esb.service.ERPIndexService;
import com.yudean.esb.security.SysAppUserService;
import com.yudean.esb.util.StringUtil;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.jws.WebService;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@WebService(endpointInterface = "com.yudean.esb.service.ERPIndexService", serviceName = "ERPIndexServiceService",targetNamespace = "http://service.esb.yudean.com/")
@Service
@Scope("prototype")
public class ERPIndexServiceImpl implements ERPIndexService {
    private final static String ENERGY_CODE = "EP";
    private final static String PROFIT_CODE = "NP";
    private final static String COMP_CODE = "SYSTEM";
    private final static org.slf4j.Logger logger = LoggerFactory.getLogger(ERPIndexServiceImpl.class);
    @Resource
    private SysAppUserService sysAppUserService;
    @Resource
    private MdsERPFinIndexDao mdsERPFinIndexDao;

    /**
     * 返回空数据的时候的信息
     *
     * @return
     */
    private static String noData() {
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><service><name>ERP财务汇总信息</name><type>发布服务</type><datalist><!--查无数据--></datalist></service>";
    }

    /**
     * 权限认证失败返回的信息
     *
     * @return
     */
    private static String noPermission() {
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><service><name>ERP财务汇总信息</name><type>发布服务</type><datalist><!--权限认证失败--></datalist></service>";
    }

    /**
     * 验证是否拥有访问的权限
     *
     * @param compCode
     * @param userName
     * @param passwd
     * @return
     */
    private boolean hasPermission(String compCode, String userName,
                                  String passwd) {
        return sysAppUserService.hasPermit(COMP_CODE, userName, passwd);
    }

    @Override
    public String getProfitByDate(String compCode, String dateCode,
                                  String userName, String passwd) {
        return getByDate(PROFIT_CODE, compCode, dateCode, userName, passwd);
    }

    @Override
    public String getEnergyByDate(String compCode, String dateCode,
                                  String userName, String passwd) {
        return getByDate(ENERGY_CODE, compCode, dateCode, userName, passwd);
    }

    /**
     * 通过 时间获取
     *
     * @param indexCode
     * @param compCode
     * @param dateCode
     * @param userName
     * @param passwd
     * @return
     */
    private String getByDate(String indexCode, String compCode,
                             String dateCode, String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return ERPIndexServiceImpl.noPermission();
        }
        if (dateCode == null || "".equals(dateCode.trim())) {
            return null;
        }

        logger.debug(
                "getByDate():reuqest-{indexCode:{},compCode:{},dataCode:{}}",
                indexCode, compCode, dateCode);
        //构造时间
        String[] timeStr = dateCode.trim().split("-");
        if (timeStr.length != 2) {
            return null;
        }

        MdsERPFinIndex bean = null;
        try {
            bean = buildBean(compCode, timeStr[0], timeStr[1]);
        } catch (Exception e) {
            return ERPIndexServiceImpl.noData();
        }

        bean.setIndexCode(indexCode); // 设置类型
        List<MdsERPFinIndex> result = mdsERPFinIndexDao.findIndex(bean);
        return handleResultList(result);
    }

    @Override
    public String getProfit(String compCode, String yearCode, String monthCode,
                            String userName, String passwd) {
        return get(PROFIT_CODE, compCode, yearCode, monthCode, userName, passwd);
    }

    @Override
    public String getEnergy(String compCode, String yearCode, String monthCode,
                            String userName, String passwd) {
        return get(ENERGY_CODE, compCode, yearCode, monthCode, userName, passwd);
    }

    private String get(String indexCode, String compCode, String yearCode,
                       String monthCode, String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return ERPIndexServiceImpl.noPermission();
        }
        if (yearCode == null || monthCode == null || "".equals(yearCode.trim())
                || "".equals(monthCode.trim())) {
            return null;
        }

        logger.debug(
                "get():request-{indexCode:{},compCode:{},yearCode:{},monthCode:{}}",
                indexCode, compCode, yearCode, monthCode);

        MdsERPFinIndex bean = null;
        try {
            bean = buildBean(compCode, yearCode, monthCode);
        } catch (Exception e) {
            return ERPIndexServiceImpl.noData();
        }

        bean.setIndexCode(indexCode);
        List<MdsERPFinIndex> list = mdsERPFinIndexDao.findIndex(bean);

        return handleResultList(list);
    }

    @Override
    public String getLastYearProfit(String compCode, String userName,
                                    String passwd) {
        return getLastYear(PROFIT_CODE, compCode, userName, passwd);
    }

    @Override
    public String getLastYearEnergy(String compCode, String userName,
                                    String passwd) {
        return getLastYear(ENERGY_CODE, compCode, userName, passwd);
    }

    private String getLastYear(String indexCode, String compCode,
                               String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return ERPIndexServiceImpl.noPermission();
        }
        Date now = new Date();
        // 需要計算去年
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        String yearCode = sdf.format(calendar.getTime());
        //避免查询到数据为空，先到数据库中查询历史数据
        String monthCode = "" + mdsERPFinIndexDao.getLastMaxMonth(Integer.parseInt(yearCode));

        logger.debug(
                "getLastYear():request-{indexCode：{},compCode:{},lastYear:{}}",
                indexCode, compCode, yearCode);

        MdsERPFinIndex bean = null;
        try {
            bean = buildBean(compCode, yearCode, monthCode);
        } catch (Exception e) {
            return ERPIndexServiceImpl.noData();
        }

        bean.setIndexCode(indexCode);

        List<MdsERPFinIndex> list = mdsERPFinIndexDao.findIndex(bean);

        return handleResultList(list);
    }

    @Override
    public String getThisYearProfit(String compCode, String userName,
                                    String passwd) {
        return getThisYear(PROFIT_CODE, compCode, userName, passwd);
    }

    @Override
    public String getThisYearEnergy(String compCode, String userName,
                                    String passwd) {
        return getThisYear(ENERGY_CODE, compCode, userName, passwd);
    }

    private String getThisYear(String indexCode, String compCode,
                               String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return ERPIndexServiceImpl.noPermission();
        }
        Date now = new Date();
        SimpleDateFormat yyyy = new SimpleDateFormat("yyyy");
        SimpleDateFormat MM = new SimpleDateFormat("MM");
        String yearCode = yyyy.format(now);
        String monthCode = MM.format(now);

        logger.debug(
                "getThisYear():request-{indexCode:{},compCode:{},thisYear:{},thisMonth:{}}",
                indexCode, compCode, yearCode, monthCode);

        MdsERPFinIndex bean = null;
        try {
            bean = buildBean(compCode, yearCode, monthCode);
        } catch (Exception e) {
            return ERPIndexServiceImpl.noData();
        }

        bean.setIndexCode(indexCode);
        List<MdsERPFinIndex> list = mdsERPFinIndexDao.getThisYear(bean);

        return handleResultList(list);
    }

    @Override
    public String getYearProfit(String compCode, String yearCode,
                                String userName, String passwd) {
        return getYear(PROFIT_CODE, compCode, yearCode, userName, passwd);
    }

    @Override
    public String getYearEnergy(String compCode, String yearCode,
                                String userName, String passwd) {
        return getYear(ENERGY_CODE, compCode, yearCode, userName, passwd);
    }

    private String getYear(String indexCode, String compCode, String yearCode,
                           String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return ERPIndexServiceImpl.noPermission();
        }

        logger.debug(
                "getYear():request-{indexCode:{},compCode:{},yearCode:{}}",
                indexCode, compCode, yearCode);

        Date now = new Date();
        SimpleDateFormat yyyy = new SimpleDateFormat("yyyy");
        String nowYear = yyyy.format(now);
        // 如果時間就為今年的話。直接調用對應的即可
        if (nowYear.equals(yearCode)) {
            return getThisYear(indexCode, compCode, userName, passwd);
        }
        String month = "12";
        MdsERPFinIndex bean = null;

        try {
            bean = buildBean(compCode, yearCode, month);
        } catch (Exception e) {
            return ERPIndexServiceImpl.noData();
        }

        bean.setIndexCode(indexCode);
        List<MdsERPFinIndex> list = mdsERPFinIndexDao.findIndex(bean);

        return handleResultList(list);
    }

    @Override
    public String getThisMothProfit(String compCode, String username,
                                    String passwd) {
        return getThisYearProfit(compCode, username, passwd);
    }

    @Override
    public String getThisMothEnergy(String compCode, String username,
                                    String passwd) {
        return getThisYearEnergy(compCode, username, passwd);
    }

    @Override
    public String getLastMonthProfit(String compCode, String userName,
                                     String passwd) {
        return getLastMonth(PROFIT_CODE, compCode, userName, passwd);
    }

    @Override
    public String getLastMonthEnergy(String compCode, String userName,
                                     String passwd) {
        return getLastMonth(ENERGY_CODE, compCode, userName, passwd);
    }

    private String getLastMonth(String indexCode, String compCode,
                                String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return ERPIndexServiceImpl.noPermission();
        }
        //根据系统的当前时间来计算上个月份，以及年份
        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONDAY) - 1);// 设置为上个月
        SimpleDateFormat yyyy = new SimpleDateFormat("yyyy");
        SimpleDateFormat MM = new SimpleDateFormat("MM");
        String yearCode = yyyy.format(now);
        String monthCode = MM.format(now);

        logger.debug(
                "getLastMonth():request-{indexCode:{},compCode:{},lastYear:{},lastMonth:{}}",
                indexCode, compCode, yearCode, monthCode);

        MdsERPFinIndex bean = buildBean(compCode, yearCode, monthCode);
        bean.setIndexCode(indexCode);
        List<MdsERPFinIndex> list = mdsERPFinIndexDao.findIndex(bean);

        return handleResultList(list);
    }

    @Override
    public String getMonthProfit(String compCode, String monthCode,
                                 String userName, String passwd) {
        return getMonth(PROFIT_CODE, compCode, monthCode, userName, passwd);
    }

    @Override
    public String getMonthEnergy(String compCode, String monthCode,
                                 String userName, String passwd) {
        return getMonth(ENERGY_CODE, compCode, monthCode, userName, passwd);
    }

    private String getMonth(String indexCode, String compCode,
                            String monthCode, String userName, String passwd) {
        if (!hasPermission(compCode, userName, passwd)) {
            return ERPIndexServiceImpl.noPermission();
        }

        logger.debug(
                "getMonth():request:{indexCode:{},compCode:{},monthCode:{}}",
                indexCode, compCode, monthCode);

        MdsERPFinIndex bean = null;
        try {
            bean = buildBean(compCode, null, monthCode);
        } catch (Exception e) {
            return ERPIndexServiceImpl.noData();
        }

        bean.setIndexCode(indexCode);
        List<MdsERPFinIndex> list = mdsERPFinIndexDao.findIndex(bean);

        return handleResultList(list);
    }

    /**
     * 将传入参数构造成一个bean
     *
     * @param compCode  公司三字码
     * @param yearCode  年份代码
     * @param monthCode 月份代码
     * @return
     */
    private MdsERPFinIndex buildBean(String compCode, String yearCode,
                                     String monthCode) throws IllegalArgumentException {
        MdsERPFinIndex bean = new MdsERPFinIndex();
        //根据输入，初始化compCode,yearCode,monthCode
        if (compCode == null || "".equals(compCode.trim())) {
            bean.setCompCode(null);
        } else {
            bean.setCompCode(compCode.trim());
        }

        if (yearCode == null || "".equals(yearCode.trim())) {
            bean.setPeriodYear(null);
        } else {
            Integer year = null;
            try {
                year = Integer.parseInt(yearCode.trim());

            } catch (Exception e) {
                logger.error("buildBean():参数不合法-{yearCode:{}}", yearCode);
                throw new IllegalArgumentException();
            }
            bean.setPeriodYear(year);
        }

        if (monthCode == null || "".equals(monthCode.trim())) {
            bean.setPeriodMonth(null);
        } else {
            Integer month = null;
            try {
                month = Integer.parseInt(monthCode.trim());
            } catch (Exception e) {
                logger.error("buildBean():参数不合法-{monthCode:{}}", monthCode);
                throw new IllegalArgumentException();
            }
            bean.setPeriodMonth(month);
        }
        return bean;
    }

    /**
     * 处理查询的结果集，包括对空集的处理
     *
     * @param list
     * @return
     */
    private String handleResultList(List<MdsERPFinIndex> list) {
        if (list == null || list.size() < 1) {
            logger.debug("No Data!");
            return ERPIndexServiceImpl.noData();
        }
        return parseList(list);
    }

    /**
     * 转换List为XML字符串
     *
     * @param list
     * @return
     */
    private String parseList(List<MdsERPFinIndex> list) {
        Document doc = null;
        doc = DocumentHelper.createDocument();
        Element root = doc.addElement("service");
        root.addElement("name").setText("ERP财务汇总信息");
        root.addElement("type").setText("发布服务");
        Element dataList = root.addElement("datalist");
        try {
            int size = list.size();
            for (int i = 0; i < size; i++) {
                MdsERPFinIndex finIndex = list.get(i);
                if (finIndex == null) {
                    continue;
                }
                Element data = dataList.addElement("data");
                this.dataWrapper(finIndex, data);
            }
            return doc.asXML();
        } catch (Exception e) {
            logger.error("parseList():error:" + e.getMessage(), e);
            return ERPIndexServiceImpl.noData();
        }
    }

    /**
     * 将对象装配到Elment中去
     *
     * @param index
     * @param data
     */
    private void dataWrapper(MdsERPFinIndex index, Element data) {
        data.addElement("compCode").setText(
                StringUtil.convertToString(index.getCompCode()));

        data.addElement("entityName").setText(
                StringUtil.convertToString(index.getEntityName()));

        data.addElement("eipName").setText(
                StringUtil.convertToString(index.getEipName()));

        data.addElement("periodYear").setText(
                StringUtil.convertToString(index.getPeriodYear()));

        data.addElement("periodMonth").setText(
                StringUtil.convertToString(index.getPeriodMonth()));

        data.addElement("periodName").setText(
                StringUtil.convertToString(index.getPeriodName()));

        data.addElement("indexCode").setText(
                StringUtil.convertToString(index.getIndexCode()));

        data.addElement("indexName").setText(
                StringUtil.convertToString(index.getIndexName()));

        data.addElement("indexValueYTD").setText(
                StringUtil.convertToString(index.getIndexValueYTD()));
    }
}
